#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef int Data_type;
//定义一个单链表结点类型
typedef struct LNode
{
	Data_type data;//数据域
	struct  LNode* next;//指针域
}linkNode, * Linklist;

//创建一个空链表
Linklist list_Create();
//尾插
int list_tail_insert(Linklist H, Data_type value);//head
//获得指定位置的结点
Linklist list_get(Linklist H, int pos);//通过pos 获得第pos个位置的结点
//头插
int list_head_insert(Linklist H, Data_type value);
//指定位置插入
int list_insert(Linklist H, Data_type value, int pos);//将value插入到第pos结点之前
//销毁链表
int list_free(Linklist *H);
//删除某一个位置上的结点
int list_delete(Linklist H, int pos);
//修改指定位置的结点数据
int list_chage_data(Linklist H,int pos,Data_type value);
// 遍历链表
int list_show(Linklist H);

int main(int argc, char const *argv[])
{
    //创建一个空的单向循环链表
    Linklist HEAD=list_Create();
    printf("尾插1,2,3,4\n");
    //尾插
    list_tail_insert(HEAD,1);
    list_tail_insert(HEAD,2);
    list_tail_insert(HEAD,3);
    list_tail_insert(HEAD,4);
    //遍历
    list_show(HEAD);
    //头插
    printf("头插7,6,5\n");
    list_head_insert(HEAD,5);
    list_head_insert(HEAD,6);
    list_head_insert(HEAD,7);
    list_show(HEAD);
    //找指定位置结点
    printf("找第4个位置结点:\n");
    Linklist t= list_get(HEAD,4);
    printf("t->data:%d\n\n",t->data);
    //在指定位置插入
    printf("在第8个位置上插入100\n");
    list_insert(HEAD,100,8);
    list_show(HEAD);
    //在指定位置删除
    printf("删除第8个位置\n");
    list_delete(HEAD,8);
    list_show(HEAD);
    //修改指定位置的结点数据
    printf("修改第5个位置上的数据为200\n");
    list_chage_data(HEAD,5,200);
    list_show(HEAD);
    //销毁
    printf("销毁链表\n");
    list_free(&HEAD);
    list_show(HEAD);
    /* code */
    return 0;
}

//--------------------------函数实现--------------------------
Linklist list_Create()
{
    Linklist head = (Linklist)malloc(sizeof(linkNode));
    if(head == NULL)
    {
        printf("malloc faild\n");
        return NULL;
    }
    head->data = 0;
    head->next = head;

    return head;
}

int list_tail_insert(Linklist H, Data_type value)
{
    if(H == NULL)
    {
        printf("list is error\n");
        return -1;
    }
    Linklist newnode = (Linklist)malloc(sizeof(linkNode));
    if(newnode==NULL)
    {
        printf("newnode malloc faild\n");
        return -1;
    }
    newnode->data=value;
    newnode->next=NULL;
    Linklist pHead = H;
    while (pHead->next != H)
    {
       pHead = pHead->next;
    }
    newnode->next = H;
    pHead->next = newnode;
    return 1;
    
}

Linklist list_get(Linklist H, int pos)
{
    if(H == NULL)
    {
        printf("list is error\n");
        return NULL;
    }
    if(H->next == H)
    {
        printf("list is empty\n");
        return NULL;
    }
    if(pos<1 && pos!=0)
    {
        printf("pos is error\n");
        return NULL;
    }
    if(pos == 0)
    {
        return H;
    }

    int i = 1;
    Linklist pHead = H->next;
    while (i < pos && pHead->next != H)
    {
        pHead = pHead->next;
        i++;
    }
    if(i < pos)
    {
        printf("pos is error2\n");
        return NULL;
    }
    return pHead;
    
}

int list_head_insert(Linklist H, Data_type value)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    Linklist newnode =(Linklist)malloc(sizeof(linkNode));
    if(newnode==NULL)
    {
        printf("newnode malloc faild\n");
        return -1;
    }
    //更新新结点的值
    newnode->data=value;
    newnode->next=NULL;
    //修改指针
    newnode->next=H->next;
    H->next=newnode;
    return 0;

}

int list_insert(Linklist H, Data_type value, int pos)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    Linklist t1=list_get(H,pos-1);
    if(t1==NULL)
    {
        return -1;
    }
    //插入
    Linklist newnode =(Linklist)malloc(sizeof(linkNode));
    if(newnode==NULL)
    {
        printf("newnode malloc faild\n");
        return -1;
    }
    //更新新结点的值
    newnode->data=value;
    newnode->next=NULL;
    //更新指针  
    newnode->next=t1->next;//把后面的数据先接上
    t1->next=newnode;//把前面的衔接上
    return 0;


}

int list_free(Linklist *H)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    Linklist phead=(*H)->next;//指向数据结点
    Linklist qhead=NULL;
    while(phead!=(*H))
    {
        qhead=phead->next;//保存要删除的结点的下一个结点
        //删除这个结点
        memset(phead,0,sizeof(linkNode));
        free(phead);
        //更新下一次要销毁的结点
        phead=qhead;
    }
    //释放 （*H）  就是头结点
    memset((*H),0,sizeof(linkNode));
    free((*H));
    *H=NULL;
    return 0;
}

// 遍历链表
int list_show(Linklist H)
{   
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    if(H->next==H)
    {
        printf("list is empty\n");
        return -1;
    }
    printf("遍历：\n");
    Linklist phead=H->next;
    while (phead!=H)
    {
        printf("%d ",phead->data);
        phead=phead->next;
    }
    printf("\n\n");
    return 0;
}

int list_delete(Linklist H, int pos)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    if(H->next==H)
    {
        printf("list is empty\n");
        return -1;
    }
    if(pos<1)
    {
        printf("pos is error\n");
        return -1;
    }
    Linklist t=list_get(H,pos-1);//t是要删除的前一个结点
    if (t==NULL)
    {
        return -1;
    }
    
    Linklist temp;//要删除的结点
    temp=t->next;
    t->next=t->next->next;//将中间要删除结点  跳过  直接连接下一个结点
    //删除  temp
    memset(temp,0,sizeof(linkNode));
    free(temp);
    return 0;

}

//修改指定位置的结点数据
int list_chage_data(Linklist H,int pos,Data_type value)
{
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
    }
    if(H->next==H)
    {
        printf("list is empty\n");
        return -1;
    }
    if(pos<1)
    {
        printf("pos is error\n");
        return -1;
    }
    Linklist t=list_get(H,pos);//
    if(t==NULL)
    {
        return -1;
    }
    //修改数据
    t->data=value;
    return 0;

}
